"""cpinfo

Obtain the current ANSI code page identifier
"""

import ctypes
import ctypes.wintypes

# from winnls.h
# typedef struct _cpinfoex {
  # UINT  MaxCharSize;
  # BYTE  DefaultChar[MAX_DEFAULTCHAR];
  # BYTE  LeadByte[MAX_LEADBYTES];
  # WCHAR UnicodeDefaultChar;
  # UINT  CodePage;
  # TCHAR CodePageName[MAX_PATH];
# }CPINFOEX, *LPCPINFOEX;

# BOOL GetCPInfoEx(
  # __in   UINT CodePage,
  # __in   DWORD dwFlags,
  # __out  LPCPINFOEX lpCPInfoEx
# );


# from windef.h
MAX_PATH = 260
# from winnls.h
MAX_LEADBYTES = 12
MAX_DEFAULTCHAR = 2
CP_ACP = 0
CP_OEMCP = 1
CP_MACCP = 2           
CP_THREAD_ACP = 3
CP_SYMBOL = 42
CP_UTF7 = 65000
CP_UTF8 = 65001

class CPINFOEXW(ctypes.Structure):
    _fields_ = (
        ('MaxCharSize'       , ctypes.wintypes.UINT,                  ),
        ('DefaultChar'       , ctypes.wintypes.BYTE*MAX_DEFAULTCHAR,  ),
        ('LeadByte'          , ctypes.wintypes.BYTE*MAX_LEADBYTES,    ),
        ('UnicodeDefaultChar', ctypes.wintypes.WCHAR,                 ),
        ('CodePage'          , ctypes.wintypes.UINT,                  ),
        ('CodePageName'      , ctypes.wintypes.WCHAR*MAX_PATH,        ),
        )

GetCPInfoExW = ctypes.windll.Kernel32.GetCPInfoExW
GetCPInfoExW.restype = ctypes.wintypes.BOOL
GetCPInfoExW.argtypes = [ctypes.wintypes.UINT, ctypes.wintypes.DWORD, ctypes.c_void_p]

def get_cp_info(cp=CP_THREAD_ACP):
    cpinfoex = CPINFOEXW()
    GetCPInfoExW(cp, 0, ctypes.byref(cpinfoex))
    return u'cp%d' % cpinfoex.CodePage, cpinfoex.CodePageName

def getwindowsencoding():
    return get_cp_info()[0]

if __name__=='__main__':
    import sys
    print (u'Current ANSI code page: %s "%s"' % get_cp_info()).encode(sys.stdout.encoding)
    print (u'Default ANSI code page: %s "%s"' % get_cp_info(CP_ACP)).encode(sys.stdout.encoding)
    print (u'Default OEM code page : %s "%s"' % get_cp_info(CP_OEMCP)).encode(sys.stdout.encoding)
    
